package com.ksframework.common.dao;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.impl.CriteriaImpl;
import org.hibernate.transform.ResultTransformer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.util.Assert;

import com.ksframework.common.entity.BaseEntity;
import com.ksframework.common.exception.DAOException;
import com.ksframework.common.util.BeanUtil;


/**
 * 提供基础的hibernate DAO模板. <p>
 * 该模板继承并封装了spring3.x <code>HibernateDaoSupport</code>.<p>
 * 
 * 常用的增删改查、分页list等.<p>
 * 注意：JDK版本一定要在1.5以上.<p>
 * <pre>
 *  static String getType(BaseEntity be)
	Session getHibernateSession() --- 加
	Object get(Class<?> clazz,Serializable id)
	Object load(Class<?> clazz,final Serializable id)
	Object findUnique(String hql, Object... values)
	Object findUniqueByProperty(Class<?> clazz,String propertyName, Object value)
	Object findUniqueByPropertyOrder(Class<?> clazz, String propertyName, Object value, Order...orders) --加
	List<?> getAll(Class<?> clazz)  改>>>>  List<?> getAll(Class<?> clazz, Order... orders)
	List<?> getAllBycriteria(Class<?> clazz)
	Page getAllByCriteria(Class<?> clazz,Page page)
	void saveOrUpdate(Object entity)
	Object save(Object entity)
	void update(Object entity)
	Object merge(Object entity)
	void persist(Object entity)
	void delete(Object entity)
	void deleteByProperty(Class clazz, String propertyName, String value)
	void deleteByLike(Class clazz, String propertyName, String value)
	void deleteByMap(Class clazz, Map<String, Object> filter)
	void deleteAll(Collection collection) --加
	void batchDelete(Class<?> clazz,final String[] ids)
	void batchSaveOrUpdate(final  List<?> list)
	void delete(Class<?> clazz,Serializable id)
	void flush()
	void clearCache(Object entity)
	void clearAllCache()
	void reloadLazy(Object proxy)
	List<?> findByHql(String hql, Object... values)
	List<?> findBySql(String sql) --加
	List<?> findByProperty(Class clazz, String property, Object value, Order...orders)
	List<?> findByLike(Class clazz, String field, String keyWord, Order...orders)
	List<?> findByMap(Class clazz, Map<String, Object> filter, Order...orders)
	List<?> findByCriteria(Class<?> clazz,Criterion... criterion)
	List<?> findByCriteria(Class<?> clazz,Criterion[] criterion,Order...order2)
	List<?> findByCriteriaSession(Criteria c)
	Query createQuery(String queryString, Object... values)
	Criteria createCriteria(Class<?> clazz,Criterion... criterions)
	Page findByCriteria(Class<?> clazz,Page page, Criterion... criterion)
	Page findByCriteriaCascade(Class<?> clazz,Page page,String[] alias, Criterion... criterions)
	void findByCriteriaCommon(Page page,Criteria c)
	Page findByCriteriaSession(Class<?> clazz,Page page, Criteria c)
	Page findByCriteriaWithAlias(Class<?> clazz, Page page, String[] alias, Criterion... criterion)
	Page<?> findAndPagination(Page page, Order order, Criteria criteria) --加
	Page<?> findAndPagination(Class clazz, Page page, Order order, Criterion[] restrictions) --加
	List<?> findEntitysByIds(Class<?> clazz, Collection<Serializable> values)
	List<?> findEntitys(List<? extends BaseEntity> values)
	int countQueryResult(Page page, Criteria c)
	Criteria getCriterion(Class clazz, Criterion[] restrictions)
	Criteria addOrder(Criteria criteria, Order[] orders)
	List<?> filterMapAndOrders2Query(Class clazz,Map<String, Object> filter, Order[] orders)
 * </pre>
 * 
 * @see #org.springframework.orm.hibernate3.support.HibernateDaoSupport()
 * @version 1.0
 */
public abstract class BaseHibernateDao<T> extends HibernateDaoSupport implements IBaseHibernateDao<T> {
	protected Logger log = LoggerFactory.getLogger(getClass());
	
	@Autowired
	public void init(SessionFactory sessionFactory){
		super.setSessionFactory(sessionFactory);
	}
		
	private static String getType(BaseEntity bean){
		return bean.getClass().getSimpleName();
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#getHibernateSession()
	 */
	@Override
	public Session getHibernateSession() {
		return getSession();
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#get(java.lang.Class, java.io.Serializable)
	 */		
	@Override
	public Object get(Class<?> clazz,Serializable id) throws DAOException {	
		return getHibernateTemplate().get(clazz,id) ;
		//或 return getSession().get(clazz,id) ;
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#load(java.lang.Class, java.io.Serializable)
	 */		
	@Override
	public Object load(Class<?> clazz,final Serializable id) throws DAOException{	
		return getHibernateTemplate().load(clazz, id);
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#findUnique(java.lang.String, java.lang.Object)
	 */
	@Override
	public Object findUnique(String hql, Object... values) throws DAOException {
		Assert.hasText(hql);
		return  createQuery(hql, values).uniqueResult();
	}

	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#findUniqueByProperty(java.lang.Class, java.lang.String, java.lang.Object)
	 */	
	@Override
	public Object findUniqueByProperty(Class<?> clazz,String propertyName, Object value) throws DAOException {
		Assert.hasText(propertyName);
		return createCriteria(clazz,Restrictions.eq(propertyName, value)).uniqueResult();
	}
	
	/*
	 * 通过属性查找唯一的对象(non-Javadoc)
	 */
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#findUniqueByPropertyOrder(java.lang.Class, java.lang.String, java.lang.Object, org.hibernate.criterion.Order)
	 */
	@Override
	public Object findUniqueByPropertyOrder(Class<?> clazz, String propertyName, Object value, Order...orders) throws DAOException {
		List<?> result = findByProperty(clazz,propertyName,value,orders);
		return (result == null || result.size() == 0 )? null : result.get(0);
	}
	

//	/**
//	 * 获取实体全部列表(loadAll方式).
//	 * @param clazz 实体类型
//	 * @return 返回实体列表.
//	 */		
//	public List<?> getAll(Class<?> clazz) throws DAOException{
//		return getHibernateTemplate().loadAll(clazz);
//	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#getAll(java.lang.Class, org.hibernate.criterion.Order)
	 */		
	@Override
	public List<?> getAll(Class<?> clazz, Order... orders) throws DAOException {
		Criteria criteria = this.getCriterion(clazz, new Criterion[0]);
		return this.addOrder(criteria, orders).list();
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#getAllListByCriteria(java.lang.Class)
	 */		
	@Override
	public List<?> getAllListByCriteria(Class<?> clazz) throws DAOException{
		return findByCriteria(clazz);
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#getAllByCriteriaOrder(java.lang.Class, org.hibernate.criterion.Order)
	 */
	@Override
	public List<?> getAllByCriteriaOrder(Class<?> clazz, Order... orders) throws DAOException{
		Criteria criteria = getSession().createCriteria(clazz);
		return this.addOrder(criteria, orders).list();
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#getAllBycriteria(java.lang.Class, com.ksframework.common.dao.Page)
	 */	
	@Override
	public Page<?> getAllBycriteria(Class<?> clazz,Page<?> page) throws DAOException{
		return findByCriteria(clazz,page);
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#saveOrUpdate(java.lang.Object)
	 */
	@Override
	public void saveOrUpdate(Object entity) throws DAOException{
		Assert.notNull(entity);
		getHibernateTemplate().saveOrUpdate(entity);	
		log.info("saveOrUpdate entity: {}", entity);
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#save(java.lang.Object)
	 */
	@Override
	public Object save(Object entity) throws DAOException{
		Assert.notNull(entity);
		getHibernateTemplate().save(entity);
		log.info("save entity: {}", entity);
		return entity;
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#update(java.lang.Object)
	 */
	@Override
	public void update(Object entity) throws DAOException{
		Assert.notNull(entity);
		getHibernateTemplate().update(entity);
		log.info("update entity: {}", entity);
	}

	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#merge(java.lang.Object)
	 */
	@Override
	public Object merge(Object entity) throws DAOException{
		Assert.notNull(entity);		
		getHibernateTemplate().merge(entity);
		log.info("merge entity: {}", entity);
		return entity;
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#persist(java.lang.Object)
	 */
	@Override
	public void persist(Object entity) throws DAOException{
		Assert.notNull(entity);		
		getHibernateTemplate().persist(entity);
		log.info("persist entity: {}", entity);
	}

	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#delete(java.lang.Object)
	 */
	@Override
	public void delete(Object entity) throws DAOException{
		Assert.notNull(entity);
		getHibernateTemplate().delete(entity);
		log.info("delete entity: {}", entity);
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#deleteByProperty(java.lang.Class, java.lang.String, java.io.Serializable)
	 */
	@Override
	public void deleteByProperty(Class<?> clazz, String propertyName, Serializable value) throws DAOException {
		StringBuffer hql = new StringBuffer();
		hql.append("delete ").append(clazz.getName()).append(" where ").append(propertyName).append(" = ").append("'").append(value).append("'");
		this.createQuery(hql.toString()).executeUpdate();
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#deleteByLike(java.lang.Class, java.lang.String, java.io.Serializable)
	 */
	@Override
	public void deleteByLike(Class<?> clazz, String propertyName, Serializable value) throws DAOException {
		StringBuffer hql = new StringBuffer();
		hql.append("delete ").append(clazz.getName()).append(" where ").append(propertyName).append(" like ").append("'").append(value).append("'");
		this.createQuery(hql.toString()).executeUpdate();
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#deleteByMap(java.lang.Class, java.util.Map)
	 */
	@Override
	public void deleteByMap(Class<?> clazz, Map<String, Object> filter) throws DAOException {
		StringBuffer hql = new StringBuffer();
		hql.append("delete ").append(clazz.getName()).append(" where 1=1");
		for(String key : filter.keySet()) {
			hql.append(" and ").append(key).append(" = ").append("'").append(filter.get(key)).append("'");
		}
		this.createQuery(hql.toString()).executeUpdate();
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#deleteAll(java.util.Collection)
	 */
	@Override
	public void deleteAll(Collection<?> collection) throws DAOException {
		getSession().delete(collection);
	}

	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#batchDelete(java.lang.Class, java.io.Serializable[])
	 */
	@Override
	public void batchDelete(Class<?> clazz,final Serializable[] ids) throws DAOException{
		Assert.notNull(ids);
		final String queryStr = "delete "+clazz.getSimpleName()+" where id in (:ids)";
		getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(queryStr);
                query.setParameterList("ids", ids);
                return query.executeUpdate();
            }
        });
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#batchSaveOrUpdate(java.util.List)
	 */
	@Override
	public void batchSaveOrUpdate(final  List<?> list) throws DAOException{
		Assert.notNull(list);
		getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {               
            	int rows = 0;
                for(int i=0;i<list.size();i++){                	
                     session.saveOrUpdate(list.get(i));                    
                     rows++;
                     if ( rows  % 10000 == 0 ) {
                    	 //将本批插入的对象立即写入数据库并释放内存
                    	 session.flush();
                    	 session.clear();
                     }
                }
                return new Integer(rows); 
            }
        });
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#delete(java.lang.Class, java.io.Serializable)
	 */
	@Override
	public void delete(Class<?> clazz,Serializable id) throws DAOException{
		Assert.notNull(id);		
		delete(get(clazz,id));
		log.info("delete entity by id: {}", id);
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#flush()
	 */
	@Override
	public void flush() throws DAOException{
		getHibernateTemplate().flush();
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#clearCache(java.lang.Object)
	 */
	@Override
	public void clearCache(Object entity) throws DAOException{
		Assert.notNull(entity);
		getHibernateTemplate().evict(entity);
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#clearAllCache()
	 */
	@Override
	public void clearAllCache() throws DAOException{
		getHibernateTemplate().clear();
	}

	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#reloadLazy(java.lang.Object)
	 */
	@Override
	public void reloadLazy(Object proxy) throws DAOException{
		Assert.notNull(proxy);
		Hibernate.initialize(proxy);
		log.info("initialize proxy: {}", proxy);
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#findByHql(java.lang.String, java.lang.Object)
	 */	
	@Override
	public List<?> findByHql(String hql, Object... values) throws DAOException{
		return createQuery(hql, values).list();
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#findBySql(java.lang.String)
	 */
	@Override
	public List<?> findBySql(String sql) throws DAOException {
		return getSession().createSQLQuery(sql).list();
	}

	/*
	 * 通过属性查找(non-Javadoc)
	 * @see com.dk.dao.IGenericDAO#findByProperty(java.lang.String, java.lang.Object, org.hibernate.criterion.Order[])
	 */
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#findByProperty(java.lang.Class, java.lang.String, java.lang.Object, org.hibernate.criterion.Order)
	 */
	@Override
	public List<?> findByProperty(Class<?> clazz, String property, Object value, Order...orders) throws DAOException {
		Map<String,Object> filter = new HashMap<String,Object>();
		filter.put(property, value);
		return this.filterMapAndOrders2Query(clazz, filter, orders);
	}
	/*
	 * 通过 %like% 查找(non-Javadoc)
	 * @see com.dk.dao.IGenericDAO#findByLike(java.lang.String, java.lang.String, org.hibernate.criterion.Order[])
	 */
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#findByLike(java.lang.Class, java.lang.String, java.lang.String, org.hibernate.criterion.Order)
	 */
	@Override
	public List<?> findByLike(Class<?> clazz, String field, String keyWord, Order...orders) throws DAOException {
		Criteria criteria = getCriterion(clazz, new Criterion[] { Restrictions.like(field, "%" + keyWord + "%") });
		return this.addOrder(criteria, orders).list();
	}
	/*
	 * 通过Map<String,Object>查找,在Map可设置多个参数(non-Javadoc)
	 * @see com.dk.dao.IGenericDAO#findByMap(java.util.Map, org.hibernate.criterion.Order[])
	 */
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#findByMap(java.lang.Class, java.util.Map, org.hibernate.criterion.Order)
	 */
	@Override
	public List<?> findByMap(Class<?> clazz, Map<String, Object> filter, Order...orders) throws DAOException {
		return this.filterMapAndOrders2Query(clazz, filter, orders);
	}
	
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#findByCriteria(java.lang.Class, org.hibernate.criterion.Criterion)
	 */	
	@Override
	public List<?> findByCriteria(Class<?> clazz,Criterion... criterion) throws DAOException{
		return createCriteria(clazz,criterion).list();
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#findByCriteria(java.lang.Class, org.hibernate.criterion.Criterion[], org.hibernate.criterion.Order)
	 */
	@Override
	public List<?> findByCriteria(Class<?> clazz,Criterion[] criterion,Order...order2) throws DAOException{
		Criteria criteria = createCriteria(clazz,criterion);
		for(Order order : order2) {
			criteria.addOrder(order);
		}
		return criteria.list();
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#findByCriteriaSession(org.hibernate.Criteria)
	 */
	@Override
	public List<?> findByCriteriaSession(Criteria c) throws DAOException{
		return c.list();
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#createQuery(java.lang.String, java.lang.Object)
	 */
	@Override
	public Query createQuery(String queryString, Object... values) throws DAOException{
		Assert.hasText(queryString);		
		Query queryObject = getSession().createQuery(queryString);
		if (values != null) {
			for (int i = 0; i < values.length; i++) {
				queryObject.setParameter(i, values[i]);
			}
		}
		return queryObject;
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#createCriteria(java.lang.Class, org.hibernate.criterion.Criterion)
	 */
	@Override
	public Criteria createCriteria(Class<?> clazz,Criterion... criterions) throws DAOException{
		Criteria criteria = getSession().createCriteria(clazz);
		if(null!=criterions && criterions.length>0){
			for (Criterion c : criterions) {
				criteria.add(c);
			}
		}
		return criteria;
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#findByCriteria(java.lang.Class, com.ksframework.common.dao.Page, org.hibernate.criterion.Criterion)
	 */
	@Override
	public Page<?> findByCriteria(Class<?> clazz,Page<?> page, Criterion... criterion) throws DAOException{
		Assert.notNull(page);

		Criteria c = createCriteria(clazz,criterion);
		this.findByCriteriaCommon(page, c);
		return page;
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#findByCriteriaCascade(java.lang.Class, com.ksframework.common.dao.Page, java.lang.String[], org.hibernate.criterion.Criterion)
	 */
	@Override
	public Page<?> findByCriteriaCascade(Class<?> clazz,Page<?> page,String[] alias, Criterion... criterions) throws DAOException{
		Assert.notNull(page);

		Criteria c = getSession().createCriteria(clazz);
		if(null!=alias && alias.length>0){
			for(String alia : alias){
				String[] arr = alia.split(",");
				String org = arr[0];//原名
				String dest = arr[1];//别名
				c.createAlias(org, dest);//创建查询对象别名
			}
		}
		for (Criterion criterion : criterions) {
			c.add(criterion);
		}
		
		this.findByCriteriaCommon(page, c);
		return page;
	}	
	/**
	 * 按Criterion分页查询,级联查询与非级联查询的公用部分.
	 * @param clazz 实体类型
	 * @param page 分页参数.包括pageSize、firstResult、orderBy、asc、autoCount.
	 *             其中firstResult可直接指定,也可以指定pageNo.
	 *             autoCount指定是否动态获取总结果数.
	 *             
	 * @param criterion 数量可变的Criterion.
	 * @param see {@link #countQueryResult(Page, Criteria)}
	 * @return 分页查询结果.附带结果列表及所有查询时的参数.
	 * @throws DAOException 
	 */	
	private void findByCriteriaCommon(Page<?> page,Criteria c) throws DAOException{
		if (page.isAutoCount()) {//如果允许自动统计,统计totalCount
			page.setRowsCount(countQueryResult(page, c));
		}
		if (page.isFirstSetted()) {
			c.setFirstResult(page.getFirst());
		}
		if (page.isPageSizeSetted()) {
			c.setMaxResults(page.getPageSize());
		}
		if (page.isOrderIndexBySetted()) {
			if (page.getOrderType().equalsIgnoreCase(Page.ASC)) {
				c.addOrder(Order.asc(page.getOrderIndex()));
			} else {
				c.addOrder(Order.desc(page.getOrderIndex()));
			}
		}

		if(page.getRowsCount()>0){
			page.setResult(c.list());
		}
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#findByCriteriaSession(java.lang.Class, com.ksframework.common.dao.Page, org.hibernate.Criteria)
	 */
	@Override
	public Page<?> findByCriteriaSession(Class<?> clazz,Page<?> page, Criteria c) throws DAOException{
		Assert.notNull(page);
		if (page.isAutoCount()) {//如果允许自动统计,统计totalCount
			page.setRowsCount(countQueryResult(page, c));
		}
		if (page.isFirstSetted()) {
			c.setFirstResult(page.getFirst());
		}
		if (page.isPageSizeSetted()) {
			c.setMaxResults(page.getPageSize());
		}
		if (page.isOrderIndexBySetted()) {
			if (page.getOrderType().equalsIgnoreCase(Page.ASC)) {
				c.addOrder(Order.asc(page.getOrderIndex()));
			} else {
				c.addOrder(Order.desc(page.getOrderIndex()));
			}
		}
		
		if(page.getRowsCount()>0){
			page.setResult(c.list());
		}
		return page;
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#findByCriteriaWithAlias(java.lang.Class, com.ksframework.common.dao.Page, java.lang.String[], org.hibernate.criterion.Criterion)
	 */
	@Override
	public Page<?> findByCriteriaWithAlias(Class<?> clazz, Page<?> page, String[] alias, Criterion... criterion) throws DAOException{
		Assert.notNull(page);
		//Criteria c = createCriteria(clazz, criterion);
		Criteria c = getSession().createCriteria(clazz);
		if(alias!=null){
			for(int i=0;i<alias.length;i++){
				String[] as = alias[i].split(":");
				if(as!=null&&as.length==2){
					c.createAlias(as[1], as[0]);
					log.debug("creating alias:{},{}",as[1],as[0]);
				}
			}
		}
		if(null!=criterion && criterion.length>0){
			for (Criterion cx : criterion) {
				c.add(cx);
			}
		}
		
		if (page.isAutoCount()) {//如果允许自动统计,统计totalCount
			page.setRowsCount(countQueryResult(page, c));
		}
		if (page.isFirstSetted()) {
			c.setFirstResult(page.getFirst());
		}
		if (page.isPageSizeSetted()) {
			c.setMaxResults(page.getPageSize());
		}
		if (page.isOrderIndexBySetted()) {
			if (page.getOrderType().equalsIgnoreCase(Page.ASC)) {
				c.addOrder(Order.asc(page.getOrderIndex()));
			} else {
				c.addOrder(Order.desc(page.getOrderIndex()));
			}
		}		

		if(page.getRowsCount()>0){
			page.setResult(c.list());
		}
		return page;
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#findAndPagination(com.ksframework.common.dao.Page, org.hibernate.criterion.Order, org.hibernate.Criteria)
	 */
	@Override
	public Page<?> findAndPagination(Page<?> page, Order order, Criteria criteria) throws DAOException{
		criteria = this.addOrder(criteria, new Order[] { order });
		page.setRowsCount((Integer) criteria.setProjection(Projections.rowCount()).uniqueResult());
		page.setPageCount(((page.getRowsCount() > 0) ? page.getRowsCount() / page.getPageSize() + 1 : (page.getRowsCount() % page.getPageSize() == 0) ? page.getRowsCount() / page.getPageSize() : 0));
		page.setResult(page.getRowsCount() == 0 ? null : criteria.setProjection(null).setFirstResult(page.getPageSize() * (page.getCurPage() - 1)).setMaxResults(page.getPageSize()).list());
		return page;
	}

	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#findAndPagination(java.lang.Class, com.ksframework.common.dao.Page, org.hibernate.criterion.Order, org.hibernate.criterion.Criterion[])
	 */
	@Override
	public Page<?> findAndPagination(Class<?> clazz, Page<?> page, Order order, Criterion[] restrictions) throws DAOException{
		this.findAndPagination(page,order, this.getCriterion(clazz,restrictions));
		return page;
	}
	
	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#findEntitysByIds(java.lang.Class, java.util.Collection)
	 */	
	@Override
	public List<?> findEntitysByIds(Class<?> clazz, Collection<Serializable> values) throws DAOException {
		Assert.notNull(values);
		StringBuffer strbf= new StringBuffer();
		for(Serializable pk:values){
			if(pk instanceof String||pk instanceof Character){
				strbf.append("'"+pk+"',");
			}else{
				strbf.append(pk+",");
			}
		}
		String parms=strbf.substring(0, strbf.length()-1).toString();
		return findByHql("from "+clazz.getSimpleName()+" as entity where entity.resourceid in("+parms+") and entity.ifdeleted = 0");
	}

	/* (non-Javadoc)
	 * @see com.ksframework.common.dao.IBaseHibernateDao#findEntitys(java.util.List)
	 */	
	@Override
	public List<?> findEntitys(List<? extends BaseEntity> values) throws DAOException {
		Assert.notNull(values);
		StringBuffer strbf = new StringBuffer();
		for(BaseEntity entity : values){
			strbf.append("'"+entity.getId()+"',");
		}
		String parms=strbf.substring(0, strbf.length()-1).toString();
		return findByHql("from "+getType(values.iterator().next())+" as entity where entity.resourceid in("+parms+") and entity.ifdeleted = 0 ");		
	}
	
	/**
	 * 通过count查询获得本次查询所能获得的对象总数.
	 * @return page对象中的totalCount属性将赋值.
	 */	
	protected int countQueryResult(Page<?> page, Criteria c) throws DAOException{
		CriteriaImpl impl = (CriteriaImpl) c;

		// 先把Projection、ResultTransformer、OrderBy取出来,清空三者后再执行Count操作
		Projection projection = impl.getProjection();
		ResultTransformer transformer = impl.getResultTransformer();

		List<CriteriaImpl.OrderEntry> orderEntries = null;
		try {
			orderEntries = (List) BeanUtil.getFieldValue(impl, "orderEntries");
			BeanUtil.setFieldValue(impl, "orderEntries", new ArrayList());
		} catch (Exception e) {
			log.error("不可能抛出的异常:{}", e.getMessage());
		}

		// 执行Count查询
		int totalCount = (Integer) c.setProjection(Projections.rowCount()).uniqueResult();
		if (totalCount < 1)
			return -1;

		// 将之前的Projection和OrderBy条件重新设回去
		c.setProjection(projection);

		if (projection == null) {
			c.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
		}
		if (transformer != null) {
			c.setResultTransformer(transformer);
		}

		try {
			BeanUtil.setFieldValue(impl, "orderEntries", orderEntries);
		} catch (Exception e) {
			log.error("不可能抛出的异常:{}", e.getMessage());
		}

		return totalCount;
	}
	
	
	
	/*
	 * @作用: 构造查询条件
	 * 	所有查询都会转变成 Criterion[],这里要把 Criterion[] 加入 Criteria
	 */
	private Criteria getCriterion(Class<?> clazz, Criterion[] restrictions) throws DAOException{
		Criteria criteria = getSession().createCriteria(clazz);
		for (Criterion c : restrictions) {
			if (null != c) {
				criteria.add(c);
			}
		}
		return criteria;
	}
	
	/*
	 * @作用: 添加Order,将所有排序 加入到 Criteria
	 */
	private Criteria addOrder(Criteria criteria, Order[] orders) throws DAOException{
		for (Order order : orders) {
			if (null != order) {
				criteria.addOrder(order);
			}
		}
		return criteria;
	}

	/*
	 * @作用: 组合查询,
	 * 支持多条件查询和多个字段排序.
	 * 使用Map<String,Object>进行查找时,这里将条件拼装成可执行的 HQL 语句
	 * 支持如下:
	 * 		0.普通条件 name = 'zhangsan'
	 * 		1.关联条件 user.name = 'zhangsan'
	 * 		2.通过Order[]连接 order by
	 * 		3.limit 进行结果限定
	 */
	private List<?> filterMapAndOrders2Query(Class<?> clazz,Map<String, Object> filter, Order[] orders) throws DAOException{
		StringBuffer content = new StringBuffer();
		content.append("From ").append(clazz.getName());
		if ((null != filter) && (!(filter.isEmpty()))) {
			Set<String> keys = filter.keySet();
			content.append(" where 1=1 ");
			for (Iterator<String> localIterator = keys.iterator(); localIterator.hasNext();) {
				String key = localIterator.next();
				if (!"limit".equalsIgnoreCase(key)) {
					content.append(" and ").append(key).append("=").append(":" + key);
				}
			}
		}
		for (Order order : orders) {
			if (order != null) {
				//TODO 多个排序条件这里好像会出错
				content.append(" order by ").append(order.toString());
			}
		}

		Query query = getSession().createQuery(content.toString());
		if (filter != null && !filter.isEmpty()) {
			Set<String> keys = filter.keySet();
			for (Iterator<String> it = keys.iterator(); it.hasNext();) {
				String key = it.next();
				if ("limit".equalsIgnoreCase(key)) {
					query.setMaxResults(Integer.parseInt(filter.get("limit").toString()));
				}else{
					query.setParameter(key, filter.get(key));
				}
			}
		}

		return query.list();
	}
}
